package com.fjn.mybatis.mybatistest;

import com.fjn.mybatis.bean.Department;
import com.fjn.mybatis.bean.Employee;
import com.fjn.mybatis.dao.*;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.util.*;

/**
 * 1.根据xml配置文件（全局配置文件(mybatis-config.xml)）创建一个SqlSessionFactory对象
 *      有数据源一些运行信息
 * 2.sql映射文件(EmployeeMapper.xml)：配置了每一个sql语句，以及sql的封装规则等
 * 3.将sql映射文件注册在全局配置文件中
 * 4.写代码
 *      （1）根据全局配置文件得到SqlSessionFactory
 *      （2）使用SqlSessionFactory，获取SqlSession对象使用它来执行sql语句进行增删改查
 *          一个SqlSession就是代表和数据库对话一次，用完关闭
 *      （3）使用sql的唯一标识来告诉Mybatis执行哪一个sql，sql都是保存在sql映射文件中的。
 */
public class MybatisTest {
    /**
     * 第一次有缺陷没有使用接口规范Employee的id（id可以填充字符等等类型）
     */
//    public static void main(String[] args) throws IOException {
//        String resource = "mybatis-config.xml";
//        InputStream inputStream = Resources.getResourceAsStream(resource);
//        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//        //获取sqlsession实例，能直接执行已经映射的sql语句
//        SqlSession openSession = sqlSessionFactory.openSession();
//        Employee emp1;
//        try {
//            emp1 = openSession.selectOne("com.fjn.mybatis.EmployeeMapper.selectEmp",1);
//            System.out.println(emp1);
//        } finally {
//            openSession.close();
//        }
//
//    }
    /**
     * 接口式编程
     * 第二种相较于第一种改善规范id（经常使用）
     */
    public static void main(String[] args) throws IOException {
        //获取全局配置文件路径
        String resourse = "com/fjn/mybatis/dao/mybatis-config.xml";
        //用IO流输入文件内容到内存
        InputStream inputStream = Resources.getResourceAsStream(resourse);
        //根据文件内容建立一个sqlsession工厂
        SqlSessionFactory sqlsessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //实例化sqlsession对象，一个sqlsession就是对数据库访问一次
        SqlSession sqlSession = sqlsessionFactory.openSession();
        try {
            //用getMapper(获取接口的实现类)
            //Mybatis会为接口自动实现一个代理对象，代理对象去执行增删改查操作
            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
            Employee emp2 = employeeMapper.getEmpById(1);
            System.out.println(emp2);
        }finally {
            sqlSession.close();

        }

    }
    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        //获取全局配置文件路径
        String resourse = "com/fjn/mybatis/dao/mybatis-config.xml";
        //用IO流输入文件内容到内存
        InputStream inputStream = Resources.getResourceAsStream(resourse);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        return sqlSessionFactory;
    }
    @Test
    public void test1() throws IOException {
        /**
         * 利用接口加注解进行映射
         */
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapper2 employeeMapper = sqlSession.getMapper(EmployeeMapper2.class);
            Employee emp3 = employeeMapper.getEmpById(1);
            System.out.println(emp3);
        } finally{
            sqlSession.close();
        }
    }
    @Test
    public void test2() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
//        获取的sqlSession不会自动提交
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
//          测试添加
//            Employee emp = new Employee(null,"sum","sum@126.com","1");
//            employeeMapper.addEmp(emp);
//            System.out.println(emp.getId());
//            测试修改信息
//            Employee emp = new Employee(1,"AIM","AIM@126.com","1");
//            employeeMapper.updateEmp(emp);
//            测试通过ID和name查找员工（参数命名例子）-----多个参数推荐使用命名参数
//            Employee emp = employeeMapper.getEmpByIdAndName(1,"AIM");
//            System.out.println(emp);
//            利用Map来通过id和name查找员工
//            Map<String,Object> map = new HashMap<>();
//            map.put("id",1);
//            map.put("name","AIM");
//            Employee emp = employeeMapper.getEmpByIdAndName1(map);
//            System.out.println(emp);
//            查询多条员工数据使用List封装
//            List<Employee> list = employeeMapper.getEmpsUseList();
//            for(Employee employee : list){
//                System.out.println(employee);
//            }
//            查询多条员工数据使用Map封装,map的key是记录中的主键，value是封装后的javaBean(该例子中id为主键，所以key是“id”)
            Map<Integer,Employee> map = employeeMapper.getEmpsUseMap();
            System.out.println(map);
//        执行sql语句
            sqlSession.commit();
        } finally{
            sqlSession.close();
        }
    }
    @Test
    public void test4() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperPlus employeeMapperPlus = sqlSession.getMapper(EmployeeMapperPlus.class);
//            ResultMap初级测试
//            Employee emp = employeeMapperPlus.getEmpById(1);
//            System.out.println(emp);
//            ResultMap多表联合查询测试
//            Employee emp = employeeMapperPlus.getEmpAndDeptById(1);
//            System.out.println(emp);
//            System.out.println(emp.getDept());
//            ResultMap多表联合查询分步查询
            Employee emp =  employeeMapperPlus.getEmpByIdStep(2);
            //此时我需要部门信息了就可以只查询部门信息
            System.out.println(emp.getDept());
            //只需要员工姓名
            System.out.println(emp.getName());
//            System.out.println(emp.getDept());
            sqlSession.commit();
        }finally {
            sqlSession.close();
        }
    }
    @Test
    public void test5() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            DepartmentMapper departmentMapper = sqlSession.getMapper(DepartmentMapper.class);
//            Department dept = departmentMapper.getDeptByIdPlus(1);
//            System.out.println(dept);
//            System.out.println(dept.getEmps());
            //分步查询
            Department dept = departmentMapper.getDeptByIdStep(1);
            System.out.println(dept);
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }
    @Test
    public void test6() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapperPlus employeeMapperPlus = sqlSession.getMapper(EmployeeMapperPlus.class);
            Employee emp = employeeMapperPlus.getEmpAndDeptById2(2);
            System.out.println(emp);
            System.out.println(emp.getDept());
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }
    @Test
//    动态sql测试
    public void test7() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeDynamicSql employeeDynamicSql = sqlSession.getMapper(EmployeeDynamicSql.class);
//            测试if/where
//            Employee emp = new Employee(null,"AIM",null,null);
//            List<Employee> emps = employeeDynamicSql.getEmpsByConditionIf(emp);
//            for(Employee emp1: emps){
//                System.out.println(emps);
//            }
//            测试trim
//            Employee emp = new Employee(null,"AIM",null,null);
//            List<Employee> emps = employeeDynamicSql.getEmpsByConditionTrim(emp);
//            for(Employee emp1: emps){
//                System.out.println(emps);
//            }
//            测试switch-case
//            Employee emp = new Employee(null,null,null,null);
//            List<Employee> emps = employeeDynamicSql.getEmpsByConditionChoose(emp);
//            for(Employee emp1: emps){
//                System.out.println(emps);
//            }
//            测试update更新操作
//            Employee emp = new Employee(1,"aim",null,null);
//            employeeDynamicSql.updateEmp(emp);
//            测试foreach遍历
            List<Employee> emps = employeeDynamicSql.foreachEmpsByCondition(Arrays.asList(1,2));
            for(Employee emp:emps){
                System.out.println(emp);
            }
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }
    @Test
    public void test8() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeDynamicSql employeeDynamicSql = sqlSession.getMapper(EmployeeDynamicSql.class);
            Employee emp1 = new Employee(null,"aaa","aaa@126.com","1",new Department(1));
            Employee emp2 = new Employee(null,"bbb","bbb@126.com","0",new Department(2));
            Employee emp3 = new Employee(null,"ccc","ccc@126.com","1",new Department(2));
            List<Employee> emps = new ArrayList<>();
            emps.add(emp1);
            emps.add(emp2);
            emps.add(emp3);
            employeeDynamicSql.addEmps(emps);
            sqlSession.commit();
        } finally {
            sqlSession.close();
        }
    }
}
